package tw.raybird.walker.officereader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;


/**
 * 只檢查壓縮檔下2層路徑
 * @author raybird
 * 
 */
public class ZipTool {
	/** 日誌器*/
	private Logger logger;
	/** 日期路徑*/
	private String date;
	/** procee 輸出*/
	private StringBuilder monitor;
	/** 是否持續監聽輸出*/
	private Boolean flag = Boolean.TRUE;
	
	public ZipTool(String date){
		logger = Logger.getRootLogger();
		this.date = date;
	}
	
	public void export(File file) {
		logger.info("讀取壓縮檔:"+ file);
		
		unZip1(file,"1");
		
		String dest = file.getAbsolutePath();
		dest = dest.replace(":","" );
		String dirpath = System.getProperty("user.dir")+"/ziptmp1/"+date+"/"+dest;
		File dir = new File(dirpath);
		List<File> dirs = new LinkedList<File>();
		dirs.add(dir);
		while(dirs.size() > 0){
			File f = dirs.get(0);
			File[] files = f.listFiles();
			for (File file2 : files) {
				if(file2.isDirectory())
					dirs.add(file2);
				else{
					String name = file2.getName();
					if(name.endsWith("zip") || name.endsWith("rar") || name.endsWith("7z")){
						unZip2(file2,"2");
					}
				}
			}
			dirs.remove(f);
		}
		logger.info("解壓縮結束 : " + file.getAbsolutePath());
	}
	
	
	/**
	 * 解壓縮
	 * @param file 壓縮檔路徑
	 * @param date 日期參數
	 * @param layer 第幾層
	 */
	private void unZip1(File file,String layer){
		logger.info("第 "+layer+" 解壓縮");
		ArrayList<String> list = new ArrayList<String>();
		
		list.add(getOS());
		list.add("e");
		list.add(file.getAbsolutePath());
		String dest = file.getAbsolutePath();
		dest = dest.replace(":","" );
		String dirpath = System.getProperty("user.dir")+"/ziptmp"+layer+"/"+date+"/"+dest;
		File dir = new File(dirpath);
		dir.mkdirs();
		list.add("-o"+dir.getAbsolutePath());
		list.add("-y");
		list.add("-r");
		String[] zipCommond = list.toArray(new String[list.size()]);
		Runtime rt = Runtime.getRuntime();
		Process pro = null;
		try {
			pro = rt.exec(zipCommond);
			zipLog(pro);
		} catch (IOException e) {
			logger.warn("", e);
		}
		finally{
			pro.destroy();
			System.gc();			
		}
	}
	
	/**
	 * 解壓縮
	 * @param file 壓縮檔路徑
	 * @param date 日期參數
	 * @param layer 第幾層
	 */
	private void unZip2(File file,String layer){
		logger.info("第 "+layer+" 解壓縮");
		ArrayList<String> list = new ArrayList<String>();
		
		list.add(getOS());
		list.add("e");
		list.add(file.getAbsolutePath());
		String dest = file.getAbsolutePath();
		dest = dest.replace(System.getProperty("user.dir")+"\\ziptmp1\\"+date+"\\","" );
		String dirpath = System.getProperty("user.dir")+"/ziptmp"+layer+"/"+date+"/"+dest;
		File dir = new File(dirpath);
		dir.mkdirs();
		list.add("-o"+dir.getAbsolutePath());
		list.add("-y");
		list.add("-r");
		String[] zipCommond = list.toArray(new String[list.size()]);
		Runtime rt = Runtime.getRuntime();
		Process pro = null;
		try {
			pro = rt.exec(zipCommond);
			zipLog(pro);
		} catch (IOException e) {
			logger.warn("", e);
		}
		finally{
			pro.destroy();
			System.gc();			
		}
	}
	
	// 抓取版本
	private static String getOS()
	{
		String OS = System.getProperty("os.name");
		if(OS.contains("Windows"))
		{
			OS = "." + File.separator + "lib" + File.separator + "7z_win" + File.separator + "7z";
		}
		if(OS.contains("Linux"))
		{
			OS = "." + File.separator + "lib" + File.separator + "7z_lin" + File.separator + "7za";
		}
		return OS;
	}
	
	private void zipLog(Process pro)
	{
		try
		{
			flag = Boolean.TRUE;
			monitor = new StringBuilder();
			InputStream in = null;
			OutputStream out = null;
			in = pro.getInputStream();
			OutputStream outputStream = pro.getOutputStream();
			watchProcess(outputStream);
			out = new FileOutputStream("./logs/7zlog.txt");
			byte[] buf = new byte[1024];
			int len;
			while((len = in.read(buf)) > 0)
			{
				out.write(buf, 0, len);
				monitor.append(new String(buf));
			}
			out.close();
			in.close();
		}
		catch(FileNotFoundException e)
		{
			logger.warn("", e);
		}
		catch(IOException e)
		{
			logger.warn("", e);
		}
		finally{
			System.gc();
			flag = Boolean.FALSE;
		}
	}
	
	/**
	 * 若是監視是否要回應Process，若是含有Enter password:
	 * 則輸出1的密碼給7z的process繼續跑，不管有沒有解成功
	 * @param outputStream
	 */
	private void watchProcess(final OutputStream outputStream) {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				while(flag){
					if(monitor.toString().contains("Enter password:")){
						try {
							String s = "1";
							outputStream.write(s.getBytes());
							outputStream.flush();
							flag = Boolean.FALSE;
						} catch (IOException e) {
							logger.warn("", e);
						}finally{
							Util.close(outputStream);
							monitor.setLength(1);
							System.gc();
						}
					}
				}
			}
		}).start();	
	}

//	public static void main(String[] args) {
//		File file = new File("C:\\Documents and Settings\\raybird\\桌面\\privacytestforder.zip");
//		new ZipTool("123").export(file);
//	}
}
